package org.jeecg.modules.oms.service.impl;

import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.extern.slf4j.Slf4j;
import org.jeecg.common.exception.JeecgBootException;
import org.jeecg.common.system.vo.LoginUser;
import org.jeecg.common.util.oConvertUtils;
import org.jeecg.modules.oms.entity.SemiProductSalesOrder;
import org.jeecg.modules.oms.entity.SemiProductSalesOrderTransaction;
import org.jeecg.modules.oms.mapper.SemiProductSalesOrderTransactionMapper;
import org.jeecg.modules.oms.service.ISemiProductSalesOrderService;
import org.jeecg.modules.oms.service.ISemiProductSalesOrderTransactionService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.apache.shiro.SecurityUtils;

import java.math.BigDecimal;
import java.util.Date;
import java.util.List;

/**
 * 半成品销售订单交易记录Service实现类
 */
@Service
@Slf4j
public class SemiProductSalesOrderTransactionServiceImpl extends ServiceImpl<SemiProductSalesOrderTransactionMapper, SemiProductSalesOrderTransaction> implements ISemiProductSalesOrderTransactionService {

    @Autowired
    private SemiProductSalesOrderTransactionMapper transactionMapper;
    
    @Autowired
    private ISemiProductSalesOrderService orderService;

    @Override
    public List<SemiProductSalesOrderTransaction> getByOrderId(String orderId) {
        if (oConvertUtils.isEmpty(orderId)) {
            return null;
        }
        try {
            return transactionMapper.selectByOrderId(orderId);
        } catch (Exception e) {
            log.error("根据订单ID查询交易记录失败: orderId={}", orderId, e);
            throw new JeecgBootException("查询交易记录失败: " + e.getMessage());
        }
    }

    @Override
    public IPage<SemiProductSalesOrderTransaction> queryTransactionPage(Page<SemiProductSalesOrderTransaction> page, SemiProductSalesOrderTransaction transaction) {
        try {
            return transactionMapper.selectTransactionPage(page, transaction);
        } catch (Exception e) {
            log.error("分页查询交易记录失败", e);
            throw new JeecgBootException("查询交易记录失败: " + e.getMessage());
        }
    }

    @Override
    public List<SemiProductSalesOrderTransaction> getByTransactionType(String orderId, Integer transactionType) {
        if (oConvertUtils.isEmpty(orderId) || transactionType == null) {
            return null;
        }
        try {
            return transactionMapper.selectByTransactionType(orderId, transactionType);
        } catch (Exception e) {
            log.error("根据交易类型查询记录失败: orderId={}, transactionType={}", orderId, transactionType, e);
            throw new JeecgBootException("查询交易记录失败: " + e.getMessage());
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean addTransaction(SemiProductSalesOrderTransaction transaction) {
        try {
            if (!validateTransaction(transaction)) {
                throw new JeecgBootException("交易记录数据验证失败");
            }

            // 获取当前用户信息
            LoginUser loginUser = (LoginUser) SecurityUtils.getSubject().getPrincipal();
            if (loginUser != null) {
                transaction.setCreateBy(loginUser.getUsername());
                if (transaction.getTenantId() == null && oConvertUtils.isNotEmpty(loginUser.getRelTenantIds())) {
                    transaction.setTenantId(Integer.parseInt(loginUser.getRelTenantIds().split(",")[0]));
                }
            }

            transaction.setCreateTime(new Date());
            if (transaction.getTransactionTime() == null) {
                transaction.setTransactionTime(new Date());
            }

            boolean result = this.save(transaction);
            if (!result) {
                throw new JeecgBootException("保存交易记录失败");
            }

            // 更新订单付款信息
            updateOrderPaymentInfo(transaction.getOrderId());

            log.info("添加交易记录成功: orderId={}, amount={}", transaction.getOrderId(), transaction.getAmount());
            return true;
        } catch (Exception e) {
            log.error("添加交易记录失败", e);
            throw new JeecgBootException("添加交易记录失败: " + e.getMessage());
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean updateTransaction(SemiProductSalesOrderTransaction transaction) {
        try {
            if (!validateTransaction(transaction)) {
                throw new JeecgBootException("交易记录数据验证失败");
            }

            // 获取当前用户信息
            LoginUser loginUser = (LoginUser) SecurityUtils.getSubject().getPrincipal();
            if (loginUser != null) {
                transaction.setUpdateBy(loginUser.getUsername());
            }

            transaction.setUpdateTime(new Date());

            boolean result = this.updateById(transaction);
            if (!result) {
                throw new JeecgBootException("更新交易记录失败");
            }

            // 更新订单付款信息
            updateOrderPaymentInfo(transaction.getOrderId());

            log.info("更新交易记录成功: id={}", transaction.getId());
            return true;
        } catch (Exception e) {
            log.error("更新交易记录失败", e);
            throw new JeecgBootException("更新交易记录失败: " + e.getMessage());
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean deleteTransaction(String id) {
        try {
            if (oConvertUtils.isEmpty(id)) {
                throw new JeecgBootException("交易记录ID不能为空");
            }

            // 获取交易记录信息
            SemiProductSalesOrderTransaction transaction = this.getById(id);
            if (transaction == null) {
                throw new JeecgBootException("交易记录不存在");
            }

            boolean result = this.removeById(id);
            if (!result) {
                throw new JeecgBootException("删除交易记录失败");
            }

            // 更新订单付款信息
            updateOrderPaymentInfo(transaction.getOrderId());

            log.info("删除交易记录成功: id={}", id);
            return true;
        } catch (Exception e) {
            log.error("删除交易记录失败", e);
            throw new JeecgBootException("删除交易记录失败: " + e.getMessage());
        }
    }

    @Override
    public BigDecimal calculatePaidAmount(String orderId) {
        try {
            if (oConvertUtils.isEmpty(orderId)) {
                return BigDecimal.ZERO;
            }
            BigDecimal result = transactionMapper.calculatePaidAmount(orderId);
            return result != null ? result : BigDecimal.ZERO;
        } catch (Exception e) {
            log.error("计算已付金额失败: orderId={}", orderId, e);
            throw new JeecgBootException("计算已付金额失败: " + e.getMessage());
        }
    }

    @Override
    public BigDecimal calculatePrepaymentAmount(String orderId) {
        try {
            if (oConvertUtils.isEmpty(orderId)) {
                return BigDecimal.ZERO;
            }
            BigDecimal result = transactionMapper.calculatePrepaymentAmount(orderId);
            return result != null ? result : BigDecimal.ZERO;
        } catch (Exception e) {
            log.error("计算预付款金额失败: orderId={}", orderId, e);
            throw new JeecgBootException("计算预付款金额失败: " + e.getMessage());
        }
    }

    @Override
    public BigDecimal calculateFinalPaymentAmount(String orderId) {
        try {
            if (oConvertUtils.isEmpty(orderId)) {
                return BigDecimal.ZERO;
            }
            BigDecimal result = transactionMapper.calculateFinalPaymentAmount(orderId);
            return result != null ? result : BigDecimal.ZERO;
        } catch (Exception e) {
            log.error("计算尾款金额失败: orderId={}", orderId, e);
            throw new JeecgBootException("计算尾款金额失败: " + e.getMessage());
        }
    }

    @Override
    public BigDecimal calculateRefundAmount(String orderId) {
        try {
            if (oConvertUtils.isEmpty(orderId)) {
                return BigDecimal.ZERO;
            }
            BigDecimal result = transactionMapper.calculateRefundAmount(orderId);
            return result != null ? result : BigDecimal.ZERO;
        } catch (Exception e) {
            log.error("计算退款金额失败: orderId={}", orderId, e);
            throw new JeecgBootException("计算退款金额失败: " + e.getMessage());
        }
    }

    @Override
    public Integer countByOrderId(String orderId) {
        try {
            if (oConvertUtils.isEmpty(orderId)) {
                return 0;
            }
            Integer result = transactionMapper.countByOrderId(orderId);
            return result != null ? result : 0;
        } catch (Exception e) {
            log.error("统计交易记录数量失败: orderId={}", orderId, e);
            throw new JeecgBootException("统计交易记录数量失败: " + e.getMessage());
        }
    }

    @Override
    public List<SemiProductSalesOrderTransaction> getByTransactionPerson(String transactionPersonId) {
        if (oConvertUtils.isEmpty(transactionPersonId)) {
            return null;
        }
        try {
            return transactionMapper.selectByTransactionPerson(transactionPersonId);
        } catch (Exception e) {
            log.error("根据交易人查询记录失败: transactionPersonId={}", transactionPersonId, e);
            throw new JeecgBootException("查询交易记录失败: " + e.getMessage());
        }
    }

    @Override
    public List<SemiProductSalesOrderTransaction> getByPaymentMethod(Integer paymentMethod) {
        if (paymentMethod == null) {
            return null;
        }
        try {
            return transactionMapper.selectByPaymentMethod(paymentMethod);
        } catch (Exception e) {
            log.error("根据支付方式查询记录失败: paymentMethod={}", paymentMethod, e);
            throw new JeecgBootException("查询交易记录失败: " + e.getMessage());
        }
    }

    @Override
    public List<SemiProductSalesOrderTransaction> getByTimeRange(Date startTime, Date endTime) {
        if (startTime == null || endTime == null) {
            return null;
        }
        try {
            return transactionMapper.selectByTimeRange(startTime, endTime);
        } catch (Exception e) {
            log.error("根据时间范围查询交易记录失败", e);
            throw new JeecgBootException("查询交易记录失败: " + e.getMessage());
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean batchInsertTransactions(List<SemiProductSalesOrderTransaction> transactionList) {
        try {
            if (transactionList == null || transactionList.isEmpty()) {
                return true;
            }

            // 获取当前用户信息
            LoginUser loginUser = (LoginUser) SecurityUtils.getSubject().getPrincipal();
            String createBy = loginUser != null ? loginUser.getUsername() : "system";
            Integer tenantId = null;
            if (loginUser != null && oConvertUtils.isNotEmpty(loginUser.getRelTenantIds())) {
                tenantId = Integer.parseInt(loginUser.getRelTenantIds().split(",")[0]);
            }

            // 设置交易记录信息
            Date now = new Date();
            for (SemiProductSalesOrderTransaction transaction : transactionList) {
                if (!validateTransaction(transaction)) {
                    throw new JeecgBootException("交易记录数据验证失败");
                }
                
                transaction.setCreateBy(createBy);
                transaction.setCreateTime(now);
                transaction.setTenantId(tenantId);
                if (transaction.getTransactionTime() == null) {
                    transaction.setTransactionTime(now);
                }
            }

            int result = transactionMapper.batchInsert(transactionList);
            if (result <= 0) {
                throw new JeecgBootException("批量插入交易记录失败");
            }

            log.info("批量插入交易记录成功: count={}", transactionList.size());
            return true;
        } catch (Exception e) {
            log.error("批量插入交易记录失败", e);
            throw new JeecgBootException("批量插入交易记录失败: " + e.getMessage());
        }
    }

    @Override
    public boolean validateTransaction(SemiProductSalesOrderTransaction transaction) {
        if (transaction == null) {
            return false;
        }

        // 验证必填字段
        if (oConvertUtils.isEmpty(transaction.getOrderId())) {
            log.error("订单ID不能为空");
            return false;
        }
        if (transaction.getTransactionType() == null) {
            log.error("交易类型不能为空");
            return false;
        }
        if (transaction.getAmount() == null || transaction.getAmount().compareTo(BigDecimal.ZERO) <= 0) {
            log.error("交易金额必须大于0");
            return false;
        }
        if (transaction.getTransactionTime() == null) {
            log.error("交易时间不能为空");
            return false;
        }

        // 验证交易类型范围
        if (transaction.getTransactionType() < 1 || transaction.getTransactionType() > 3) {
            log.error("交易类型必须在1-3之间");
            return false;
        }

        // 验证支付方式范围
        if (transaction.getPaymentMethod() != null && 
            (transaction.getPaymentMethod() < 1 || transaction.getPaymentMethod() > 5)) {
            log.error("支付方式必须在1-5之间");
            return false;
        }

        return true;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean processPayment(String orderId, BigDecimal amount, Integer transactionType, 
                                 Integer paymentMethod, String transactionPersonId, 
                                 String description, String voucher) {
        try {
            SemiProductSalesOrderTransaction transaction = new SemiProductSalesOrderTransaction();
            transaction.setOrderId(orderId);
            transaction.setTransactionType(transactionType);
            transaction.setAmount(amount);
            transaction.setPaymentMethod(paymentMethod);
            transaction.setTransactionPersonId(transactionPersonId);
            transaction.setDescription(description);
            transaction.setTransactionVoucher(voucher);

            return addTransaction(transaction);
        } catch (Exception e) {
            log.error("处理付款失败", e);
            throw new JeecgBootException("处理付款失败: " + e.getMessage());
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean processRefund(String orderId, BigDecimal amount, String transactionPersonId, 
                                String description, String reason) {
        try {
            SemiProductSalesOrderTransaction transaction = new SemiProductSalesOrderTransaction();
            transaction.setOrderId(orderId);
            transaction.setTransactionType(3); // 退款
            transaction.setAmount(amount);
            transaction.setTransactionPersonId(transactionPersonId);
            transaction.setDescription(description);
            transaction.setRemark(reason);

            return addTransaction(transaction);
        } catch (Exception e) {
            log.error("处理退款失败", e);
            throw new JeecgBootException("处理退款失败: " + e.getMessage());
        }
    }

    /**
     * 更新订单付款信息
     * @param orderId 订单ID
     */
    private void updateOrderPaymentInfo(String orderId) {
        try {
            if (oConvertUtils.isEmpty(orderId)) {
                return;
            }

            // 计算已付金额
            BigDecimal paidAmount = calculatePaidAmount(orderId);
            
            // 获取订单总金额
            SemiProductSalesOrder order = orderService.getById(orderId);
            if (order == null) {
                return;
            }

            BigDecimal totalAmount = order.getTotalAmount() != null ? order.getTotalAmount() : BigDecimal.ZERO;
            BigDecimal unpaidAmount = totalAmount.subtract(paidAmount);
            
            // 确定付款状态
            Integer payStatus = 0; // 默认未付清
            if (paidAmount.compareTo(BigDecimal.ZERO) > 0) {
                if (paidAmount.compareTo(totalAmount) >= 0) {
                    payStatus = 1; // 已付清
                    unpaidAmount = BigDecimal.ZERO;
                }
            }

            // 更新订单金额信息
            LoginUser loginUser = (LoginUser) SecurityUtils.getSubject().getPrincipal();
            String updateBy = loginUser != null ? loginUser.getUsername() : "system";
            
            orderService.updateOrderAmount(orderId, totalAmount, paidAmount, unpaidAmount, payStatus, updateBy);
        } catch (Exception e) {
            log.error("更新订单付款信息失败: orderId={}", orderId, e);
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean deleteByOrderId(String orderId) {
        if (oConvertUtils.isEmpty(orderId)) {
            throw new JeecgBootException("订单ID不能为空");
        }
        
        try {
            // 获取当前用户信息
            LoginUser loginUser = (LoginUser) SecurityUtils.getSubject().getPrincipal();
            String updateBy = loginUser != null ? loginUser.getUsername() : "system";
            
            // 查询该订单的所有交易记录
            List<SemiProductSalesOrderTransaction> transactions = this.getByOrderId(orderId);
            //删除所有交易记录
            this.removeByIds(transactions);
            
            return true;
        } catch (Exception e) {
            log.error("根据订单ID删除交易记录失败: orderId={}", orderId, e);
            throw new JeecgBootException("删除交易记录失败: " + e.getMessage());
        }
    }
}
